package persistence;

import interfaces.IDataFiles;
import interfaces.IGameManagement;

import java.io.File;
import java.io.IOException;
import java.io.Serializable;
import java.rmi.RemoteException;
import java.util.ArrayList;
import java.util.List;
import java.util.Vector;

import net.GameManagement;
import tools.MyTools;
import valueObjects.game.Player;
import valueObjects.game.card.Card;
import valueObjects.game.card.door.DoorCard;
import valueObjects.game.card.treasure.TreasureCard;
import exception.game.SaveFileNotFoundException;

/**
 * This class manages the data files.
 */
public class DataFiles implements Serializable, IDataFiles {

	private static final String SMALLICONS = "smallIcons";
	
	private static final String DETAILICONS = "detailIcons";
	
	private static final String CARDS = "Cards";
	
	private static final String RESOURCES_CARDS = "resources/cards";
	
	private static final long serialVersionUID = 1L;

	private static IPersistenceManager pManager = new FilePersistenceManager();
	
	private static String mainFile;
	
	private static final String SAVEGAMES = "savegames";

	private static final String BACKICON_TREASURE = "backIconTreasure.png";
	
	private static final String BACKICON_DOOR = "backIconDoor.png";
	
	/**
	 * Constructor with the main resources.
	 * @param fileResource
	 */
	public DataFiles(String fileResource){
		mainFile = fileResource;
	}
	
	/**
	 * Returns the mainFile
	 * @return String
	 */
	public String getMainFile() throws RemoteException{
		return mainFile;
	}

	/**
	 * Reading in the Playersfile and return it
	 * @return String
	 */
	public String getPlayersFile() throws RemoteException {
		String result = "";
		try {
			pManager.openForReading(mainFile);
			List<String> fileSource = new ArrayList<String>();
			boolean linesLeft = true;
			while (linesLeft) {
				String readLine = pManager.readLine();
				if (readLine != null) {
					String line[] = readLine.split(":");
					fileSource.add(line[1]);
				} else {
					linesLeft = false;
				}
			}
			pManager.close();
			result = fileSource.get(7);
		} catch (IOException e) {
			e.printStackTrace();
		}
		return result;
	}
	
	/**
	 * Generates a file for saving/loading a game
	 * @param vector
	 * @param fileName
	 * @return String the file
	 */
	public static String generateFile(Vector<Player> vector, String fileName) throws RemoteException {
		String file = "";
		for (Player player : vector) {
			file += player.getName() + "_";
		}
		return MyTools.isEmpty(fileName) ? file : SAVEGAMES + "/" + file + fileName;
	}
	
	/**
	 * Loads a game by the given parameters.
	 * @param vector
	 * @param file
	 * @return {@link GameManagement}
	 * @throws SaveFileNotFoundException
	 * @throws RemoteException 
	 */
	public IGameManagement loadGame(Vector<Player> vector, String file) throws SaveFileNotFoundException, RemoteException {
		String fileName = generateFile(vector, file);
		GameManagement result = null;
		try {
			pManager.openForReadingSer(fileName);
			result = pManager.loadGame();
			pManager.close();
		} catch (IOException | ClassNotFoundException e) {
			pManager.close();
			throw new SaveFileNotFoundException(fileName);
		}
		return result;
	}
	
	/**
	 * Load the Savegames with the given currentPlayer and return it
	 * @return ArrayList<String>
	 * @throws RemoteException
	 */
	public List<String> savegames(Vector<Player> currentPlayers) throws RemoteException {
		File dir = new File("savegames");
		File[] files = dir.listFiles();
		List<String> result = new ArrayList<String>();
		String pattern = generateFile(currentPlayers, "");
		if(files != null){
			for (File f : files) {
				String name = f.getName();
				if(name.contains(pattern)){
					result.add(name.substring(pattern.length(), name.length()));
				}
			}
		}
		return result;
	}

	/**
	 * Loading the Path for the Images of the given card c
	 * @return String
	 */
	public static String getSmallIcon(Card c) {
		return RESOURCES_CARDS + "/" + c.getType() + CARDS + "/" + SMALLICONS + "/" + c.getLabel() + ".png";
	}

	/**
	 * Loading the Path for the Backsideimages of the given card c
	 * @return String
	 */
	public static String getBackIcon(Card c) {
		if(c instanceof DoorCard){
			return RESOURCES_CARDS + "/" + BACKICON_DOOR;
		} else if(c instanceof TreasureCard){
			return RESOURCES_CARDS + "/" + BACKICON_TREASURE;
		}
		return null;
	}


	public static String getDetailIcon(Card c) {
		return RESOURCES_CARDS + "/" + c.getType() + CARDS + "/" + DETAILICONS + "/" + c.getLabel() + ".png";
	}
	
}
